# -*- coding: utf-8 -*-
"""
Created on
@Time: 2024/12/23 8:18
@Author: Mr.Z
@contact: <QQ:40061980>
@contact: bob@pheks.com
@File: configPage.py
@IDE: PyCharm
@Python Version：
"""

import ftplib
import smtplib
from datetime import datetime
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from Crypto.Random import get_random_bytes
from PySide6.QtWidgets import QWidget, QVBoxLayout, QFormLayout, QLineEdit, QGroupBox, QPushButton, QMessageBox

from utils.encrypt import encrypt_password, decrypt_password
from database.database import get_database  # 导入数据库连接模块
from database.models import Config  # 导入数据库模型模块
from utils.log_recorder import setup_logger as logger  # 导入日志记录模块


class ConfigPage(QWidget):
    """配置页面UI"""

    def __init__(self, log_text_edit):
        super().__init__()
        self.log_text_edit = log_text_edit

        # 创建主布局
        main_layout = QVBoxLayout()

        # 创建接口配置组
        interface_group = QGroupBox("接口配置")
        interface_layout = QFormLayout()

        self.url_input = QLineEdit()
        self.url_input.setPlaceholderText("请输入Api URL")
        interface_layout.addRow("API URL:", self.url_input)

        self.appid_input = QLineEdit()
        self.appid_input.setPlaceholderText("请输入APP ID")
        interface_layout.addRow("APP ID:", self.appid_input)

        self.appkey_input = QLineEdit()
        self.appkey_input.setPlaceholderText("请输入APP KEY")
        self.appkey_input.setEchoMode(QLineEdit.Password)  # 设置为密码输入模式
        interface_layout.addRow("APP KEY:", self.appkey_input)

        interface_group.setLayout(interface_layout)
        main_layout.addWidget(interface_group)

        # 创建邮箱配置组
        email_group = QGroupBox("邮箱配置")
        email_layout = QFormLayout()

        self.from_email_input = QLineEdit()
        self.from_email_input.setPlaceholderText("请输入发件邮箱地址")
        email_layout.addRow("发件邮箱:", self.from_email_input)

        self.from_email_password_input = QLineEdit()
        self.from_email_password_input.setPlaceholderText("请输入发件邮箱密码或授权码")
        self.from_email_password_input.setEchoMode(QLineEdit.Password)  # 设置为密码输入模式
        email_layout.addRow("发件邮箱密码:", self.from_email_password_input)

        self.smtp_server_input = QLineEdit()
        self.smtp_server_input.setPlaceholderText("请输入SMTP服务器地址")
        email_layout.addRow("SMTP服务器:", self.smtp_server_input)

        self.smtp_port_input = QLineEdit()
        self.smtp_port_input.setPlaceholderText("请输入SMTP服务器的SSL端口")
        email_layout.addRow("SMTP端口:", self.smtp_port_input)

        self.to_email_input = QLineEdit()
        self.to_email_input.setPlaceholderText("请输入收件邮箱地址")
        email_layout.addRow("收件邮箱:", self.to_email_input)

        # 创建发送测试邮件按钮
        self.test_email_button = QPushButton("发送测试邮件")
        self.test_email_button.clicked.connect(self.test_email)
        email_layout.addRow("发件测试:", self.test_email_button)

        email_group.setLayout(email_layout)
        main_layout.addWidget(email_group)

        # 创建FTP配置组
        ftp_group = QGroupBox("FTP配置")
        ftp_layout = QFormLayout()

        self.ftp_host_input = QLineEdit()
        self.ftp_host_input.setPlaceholderText("请输入FTP主机地址")
        ftp_layout.addRow("FTP主机地址:", self.ftp_host_input)

        self.ftp_user_input = QLineEdit()
        self.ftp_user_input.setPlaceholderText("请输入FTP用户名")
        ftp_layout.addRow("FTP用户名:", self.ftp_user_input)

        self.ftp_password_input = QLineEdit()
        self.ftp_password_input.setPlaceholderText("请输入FTP密码")
        self.ftp_password_input.setEchoMode(QLineEdit.Password)  # 设置为密码输入模式
        ftp_layout.addRow("FTP密码:", self.ftp_password_input)

        self.ftp_port_input = QLineEdit()
        self.ftp_port_input.setPlaceholderText("请输入FTP端口")
        ftp_layout.addRow("FTP端口:", self.ftp_port_input)

        # 创建FTP连接测试按钮
        self.test_ftp_button = QPushButton("连接测试")
        self.test_ftp_button.clicked.connect(self.test_ftp_connection)
        ftp_layout.addRow("连接测试:", self.test_ftp_button)

        ftp_group.setLayout(ftp_layout)
        main_layout.addWidget(ftp_group)

        # 创建保存按钮
        self.save_button = QPushButton("保存")
        self.save_button.clicked.connect(self.save_config)
        main_layout.addWidget(self.save_button)

        # 设置中心部件的布局
        self.setLayout(main_layout)

        # 加载保存的配置
        self.load_saved_config()

    def save_config(self):
        """保存配置，点击配置页面保存按钮时调用"""
        try:
            database = get_database()  # 获取数据库会话
            logger().info("[configPage-save_config]-获取数据库会话成功")

            # TODO：生成随机key功能正常
            # 生成随机的key，用于加密密码
            key_for_appkey = get_random_bytes(16)
            key_for_email_password = get_random_bytes(16)
            key_for_ftp_password = get_random_bytes(16)

            # TODO：加密密码在用户点击保存时会在已加密的基础上再次加密，正常应该是只加密一次
            # 加密密码
            # new_appkey = encrypt_password(self.appkey_input.text(), key_for_appkey).hex()
            # new_from_email_password = encrypt_password(self.from_email_password_input.text(),
            #                                            key_for_email_password).hex()
            # new_ftp_password = encrypt_password(self.ftp_password_input.text(),
            #                                     key_for_ftp_password).hex()

            config_first = database.query(Config).first()  # 获取数据库中第一条配置数据

            if config_first:
                # 更新旧的配置数据
                config_first.url = self.url_input.text()
                config_first.appid = self.appid_input.text()
                config_first.appkey = self.appkey_input.text()  # 未加密的appkey
                # config_first.appkey = new_appkey  # 加密后的appkey
                config_first.key_for_appkey = key_for_appkey.hex()
                config_first.from_email = self.from_email_input.text()
                config_first.from_email_password = self.from_email_password_input.text()  # 未加密的发件邮箱密码
                # config_first.from_email_password = new_from_email_password  # 加密后的发件邮箱密码
                config_first.key_for_email_password = key_for_email_password.hex()
                config_first.smtp_server = self.smtp_server_input.text()
                config_first.smtp_port = self.smtp_port_input.text()
                config_first.to_email = self.to_email_input.text()
                config_first.ftp_host = self.ftp_host_input.text()
                config_first.ftp_user = self.ftp_user_input.text()
                config_first.ftp_password = self.ftp_password_input.text()  # 未加密的FTP密码
                # config_first.ftp_password = new_ftp_password  # 加密后的FTP密码
                config_first.key_for_ftp_password = key_for_ftp_password.hex()
                config_first.ftp_port = self.ftp_port_input.text()
                database.commit()
                logger().info("[configPage-save_config]-更新旧的配置数据成功")
            else:

                # 插入新的配置数据
                new_config = Config(
                    url=self.url_input.text(),
                    appid=self.appid_input.text(),
                    appkey=self.appkey_input.text(),  # 未加密的appkey
                    # appkey=new_appkey,  # 加密后的appkey
                    key_for_appkey=key_for_appkey.hex(),
                    from_email=self.from_email_input.text(),
                    from_email_password=self.from_email_password_input.text(),  # 未加密的发件邮箱密码
                    # from_email_password=new_from_email_password,  # 加密后的发件邮箱密码
                    key_for_email_password=key_for_email_password.hex(),
                    smtp_server=self.smtp_server_input.text(),
                    smtp_port=self.smtp_port_input.text(),
                    to_email=self.to_email_input.text(),
                    ftp_host=self.ftp_host_input.text(),
                    ftp_user=self.ftp_user_input.text(),
                    ftp_password=self.ftp_password_input.text(),  # 未加密的FTP密码
                    # ftp_password=new_ftp_password,  # 加密后的FTP密码
                    key_for_ftp_password=key_for_ftp_password.hex(),
                    ftp_port=self.ftp_port_input.text()
                )

                database.add(new_config)  # 添加到数据库
                database.commit()  # 提交事务
                logger().info("[configPage-save_config]-已插入新的配置数据")

            # 关闭会话
            database.close()
            logger().info("[configPage-save_config]-已关闭数据库会话")

            QMessageBox.information(self, "成功", "配置已保存")
            self.log_text_edit.appendPlainText(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 配置已保存")
            logger().info("[configPage-save_config]-配置已保存")

        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存配置时出错: {e}")
            self.log_text_edit.appendPlainText(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 保存配置时出错: {e}")
            logger().error(f"[configPage-save_config]-保存配置时出错: {e}")

    def load_saved_config(self):
        """加载保存的配置，使其显示在配置页面上"""
        try:
            database = get_database()  # 获取数据库会话
            logger().info("[configPage-load_saved_config]-获取数据库会话成功")

            # 查询最新的配置数据
            config = database.query(Config).order_by(Config.id.desc()).first()
            logger().info("[configPage-load_saved_config]-查询最新的配置数据成功")

            if config:
                self.url_input.setText(config.url)
                self.appid_input.setText(config.appid)
                self.appkey_input.setText(config.appkey)
                self.from_email_input.setText(config.from_email)
                self.from_email_password_input.setText(config.from_email_password)
                self.smtp_server_input.setText(config.smtp_server)
                self.smtp_port_input.setText(config.smtp_port)
                self.to_email_input.setText(config.to_email)
                self.ftp_host_input.setText(config.ftp_host)
                self.ftp_user_input.setText(config.ftp_user)
                self.ftp_password_input.setText(config.ftp_password)
                self.ftp_port_input.setText(config.ftp_port)

            # 关闭会话
            database.close()
            logger().info("[configPage-load_saved_config]-已关闭数据库会话")

        except Exception as e:
            QMessageBox.critical(self, "错误", f"加载配置时出错: {e}")
            self.log_text_edit.appendPlainText(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 加载配置时出错: {e}")
            logger().error(f"[configPage-load_saved_config]-加载配置时出错: {e}")

    def test_email(self):
        """测试邮箱配置，点击配置页面发送测试邮件按钮时调用"""
        try:
            database = get_database()  # 获取数据库会话
            logger().info("[configPage-test_email]-获取数据库会话成功")

            # 查询发件邮箱密码和key
            config = database.query(Config).first()
            logger().info("[configPage-test_email]-查询发件邮箱密码和key成功")

            if not config:
                QMessageBox.warning(self, "警告", "未找到配置信息")
                self.log_text_edit.appendPlainText(
                    f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 未找到配置信息")
                logger().warning("[configPage-test_email]-未找到配置信息")
                return

            # 获取加密后的发件邮箱密码和key并转换为字节格式
            # encrypted_from_email_password = bytes.fromhex(config.from_email_password)
            # key_for_email_password = bytes.fromhex(config.key_for_email_password)

            # 解密密码
            # from_email_password = decrypt_password(encrypted_from_email_password, key_for_email_password)
            from_email_password = config.from_email_password

            from_email = self.from_email_input.text()
            smtp_server = self.smtp_server_input.text()
            smtp_port = int(self.smtp_port_input.text())
            to_email = self.to_email_input.text()

            if not all([from_email, from_email_password, smtp_server, smtp_port, to_email]):
                QMessageBox.warning(self, "警告", "请填写所有邮箱配置项")
                self.log_text_edit.appendPlainText(
                    f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 未填写所有邮箱配置项")
                logger().warning("[configPage-test_email]-未填写所有邮箱配置项")
                return

            # 创建邮件内容
            message = MIMEMultipart()
            message['From'] = from_email
            message['To'] = to_email
            message['Subject'] = "测试邮件"
            body = "这是一封测试邮件，用于验证邮箱配置是否正确。"
            message.attach(MIMEText(body, 'plain'))

            # 连接到SMTP服务器并发送邮件
            with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
                logger().info(f"[configPage-test_email]-连接到SMTP服务器: {smtp_server}:{smtp_port}成功")
                server.login(from_email, from_email_password)
                logger().info(f"[configPage-test_email]-登录到SMTP服务器成功")
                server.sendmail(from_email, to_email, message.as_string())

            QMessageBox.information(self, "成功", "测试邮件已发送")
            self.log_text_edit.appendPlainText(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 测试邮件已发送")
            logger().info("[configPage-test_email]-测试邮件已发送")

            # 关闭会话
            database.close()
            logger().info("[configPage-test_email]-已关闭数据库会话")

        except Exception as e:
            QMessageBox.critical(self, "错误", f"发送测试邮件时出错: {e}")
            self.log_text_edit.appendPlainText(
                f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 发送测试邮件时出错: {e}")
            logger().error(f"[configPage-test_email]-发送测试邮件时出错: {e}")

    def test_ftp_connection(self):
        """测试FTP配置，点击配置页面连接测试按钮时调用"""

        try:
            ftp_host = self.ftp_host_input.text()
            ftp_user = self.ftp_user_input.text()
            ftp_password = self.ftp_password_input.text()
            ftp_port = int(self.ftp_port_input.text()) if self.ftp_port_input.text() else 21  # 默认端口为21

            if not all([ftp_host, ftp_user, ftp_password]):
                QMessageBox.warning(self, "警告", "请填写所有FTP配置项")
                self.log_text_edit.appendPlainText(
                    f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: 未填写所有FTP配置项")
                logger().warning("[configPage-test_ftp_connection]-未填写所有FTP配置项")
                return

            with ftplib.FTP() as ftp:
                ftp.connect(ftp_host, ftp_port)
                ftp.login(ftp_user, ftp_password)
                logger().info(f"[configPage-test_ftp_connection]-连接到FTP服务器: {ftp_host}:{ftp_port} 成功")

                QMessageBox.information(self, "成功", "FTP连接测试成功")
                self.log_text_edit.appendPlainText(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: FTP连接测试成功")
                logger().info("[configPage-test_ftp_connection]-FTP连接测试成功")

        except Exception as e:
            QMessageBox.critical(self, "错误", f"FTP连接测试失败: {e}")
            self.log_text_edit.appendPlainText(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: FTP连接测试失败: {e}")
            logger().error(f"[configPage-test_ftp_connection]-FTP连接测试失败: {e}")
